﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO.IsolatedStorage;
using System.IO;
using System.Windows.Media.Imaging;

namespace slTestingStreaming.Libraries
{
    public class IsolatedStorage
    {
        private const string SAVEDIMG = "SavedBitmapImage.xyz";


        public static Image LoadImage(string fileName)
        {

            byte[] buffer = _LoadIfExists(fileName);

            if (buffer.Length > 0)
            {
                Image i = new Image();
                i.Source = _GetImage(buffer);
                return i;
            }
            else
            {
                return null;
            }
        }


        public static void SaveImage(WriteableBitmap bitmap, string filename)
        {

            _SaveToDisk(_GetSaveBuffer(bitmap), filename);    

        }



        /// <summary>
        ///     Load file, if it exists
        /// </summary>
        /// <param name="fileName">The filename</param>
        /// <returns>The byte array for the file</returns>
        private static byte[] _LoadIfExists(string fileName)
        {
            byte[] retVal;

            using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (iso.FileExists(fileName))
                {
                    using (IsolatedStorageFileStream stream = iso.OpenFile(fileName, FileMode.Open))
                    {
                        retVal = new byte[stream.Length];
                        stream.Read(retVal, 0, retVal.Length);
                    }
                }
                else
                {
                    retVal = new byte[0];
                }
            }
            return retVal;
        }

        /// <summary>
        ///     Saves to isolated storage
        /// </summary>
        /// <param name="buffer">The buffer</param>
        /// <param name="fileName"></param>
        private static void _SaveToDisk(byte[] buffer, string fileName)
        {
            using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (
                    IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.CreateNew,
                                                                                     iso))
                {
                    stream.Write(buffer, 0, buffer.Length);
                }
            }
        }

        /// <summary>
        ///     Gets an image from storage
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns>The bitmap</returns>
        private static WriteableBitmap _GetImage(byte[] buffer)
        {
            int width = buffer[0]*256 + buffer[1];
            int height = buffer[2]*256 + buffer[3];

            long matrixSize = width*height;

            WriteableBitmap retVal = new WriteableBitmap(width, height);

            int bufferPos = 4; 

            for (int matrixPos = 0; matrixPos < matrixSize; matrixPos++)
            {
                int pixel = buffer[bufferPos++];
                pixel = pixel << 8 | buffer[bufferPos++];
                pixel = pixel << 8 | buffer[bufferPos++];
                pixel = pixel << 8 | buffer[bufferPos++];
                retVal.Pixels[matrixPos] = pixel;
            }

            return retVal; 
        }

        /// <summary>
        ///     Gets the buffer to save to disk from the writeable bitmap
        /// </summary>
        /// <param name="bitmap">The bitmap image</param>
        /// <returns>The buffer of bytes</returns>
        private static byte[] _GetSaveBuffer(WriteableBitmap bitmap)
        {
            long matrixSize = bitmap.PixelWidth*bitmap.PixelHeight;
            
            long byteSize = matrixSize*4 + 4; 

            byte[] retVal = new byte[byteSize];

            long bufferPos = 0;

            retVal[bufferPos++] = (byte) ((bitmap.PixelWidth / 256) & 0xff);
            retVal[bufferPos++] = (byte) ((bitmap.PixelWidth % 256) & 0xff);
            retVal[bufferPos++] = (byte) ((bitmap.PixelHeight / 256) & 0xff);
            retVal[bufferPos++] = (byte) ((bitmap.PixelHeight % 256) & 0xff);

            for (int matrixPos = 0; matrixPos < matrixSize; matrixPos++)
            {
                retVal[bufferPos++] = (byte)((bitmap.Pixels[matrixPos] >> 24) & 0xff);
                retVal[bufferPos++] = (byte)((bitmap.Pixels[matrixPos] >> 16) & 0xff);
                retVal[bufferPos++] = (byte)((bitmap.Pixels[matrixPos] >> 8) & 0xff);
                retVal[bufferPos++] = (byte)((bitmap.Pixels[matrixPos]) & 0xff);    
            }

            return retVal;
        }

    }
}
